#include "testApp.h"
#include "networkConstants.h"
#define RECONNECT_TIME 400

//--------------------------------------------------------------
void testApp::setup(){	 
	//server = "hjemme.ole.kristensen.name";
	server = "192.168.1.117";
	tcpPort = 11993;
	udpPort = 11990;
	// we don't want to be running to fast
	ofSetVerticalSync(true);
	ofSetFrameRate(60);
	//load our type
	mono.loadFont("type/mono.ttf",9);
	monosm.loadFont("type/mono.ttf",8);

	//are we connected to the server - if this fails we 
	//will check every few seconds to see if the server exists
	tcpClient.setVerbose(true);


	weConnected = tcpClient.setup(server, tcpPort);
	udpClient.Create();
	udpClient.Connect((char *)server.c_str(), udpPort);
//	udpClient.SetTimeoutSend(1);
//	weConnected = tcpClient.setup("localhost", 11995);
	serverConnected = false;

	tcpClient.sendAdr(ADR_HANDSHAKE,"player");

	connectTime = 0;	
		
	waitingForPingResponse = false;
	
}

//--------------------------------------------------------------
void testApp::update(){
	string msg = " test besked"+ofToString(ofGetElapsedTimeMillis(), 0);
	udpClient.SendAll(msg.c_str(), strlen(msg.c_str()));
	ofBackground(230, 230, 230);	
	//if data has been sent lets update our text
	string str = tcpClient.receiveRaw();
	if( str.length() > 0 ){
//		cout<<str<<endl;

		string sSTR_END_MSG = "[/TCP]"; 
		int pos = str.find(sSTR_END_MSG, 0); 
		msgRx = str;
		cout<<"Msg received: "<<str<<endl;

		while(pos >= 0 && str.length() > 0){ 
			string command = str.substr(0, pos); 
			//cout<<"Command: "<<command<<endl;
			str = str.substr(pos + sSTR_END_MSG.length()); 
			pos = str.find(STR_END_MSG, 0); 	
			if(command.length() > 0){
				switch (command[0]) {
					case ADR_HANDSHAKE:
						cout<<"Handshake with server"<<endl;
						playerNumber = atoi(command.substr(1,1).c_str());
						cout<<"Player: "<<playerNumber<<endl;
						serverConnected = true;
						break;
					case ADR_PING:
						latency = ofGetElapsedTimeMillis() - atoi(command.substr(1).c_str());
						waitingForPingResponse = false;
						break;
					case ADR_PLAYER_POSX:
						int p = atoi(command.substr(1, 1).c_str());
						if(p<2){
//							cout<<"Set pos for player "<<p+1<<" to "<<strtod(command.substr(2).c_str(), NULL)<<endl;
							players[p].posX = strtod(command.substr(2).c_str(), NULL);
						}
						break;
					case ADR_SET_PLAYER_NUMBER:
					//	playerNumber = atoi(command.substr(1,1).c_str());
					//	cout<<"Player: "<<playerNumber<<endl;
						break;
					default:
						break;
				}
			}
		}
	}
	
	if(serverConnected){
		timeSincePing += ofGetElapsedTimeMillis()-dT;
		timeSincePlayerUpdate += ofGetElapsedTimeMillis()-dT;

		if(timeSincePing > 1000 && waitingForPingResponse == false){
			tcpClient.sendAdr(ADR_PING,ofToString(ofGetElapsedTimeMillis(), 0));
			timeSincePing = 0;
			waitingForPingResponse = true;
		} else if(timeSincePing > 3000){
			//Lost connection to server 
			weConnected = false;
			serverConnected = false;
			tcpClient.close();
		} else {
			if(timeSincePlayerUpdate > 100){
				tcpClient.sendAdr(ADR_PLAYER_POSX, ofToString(playerNumber-1)+ofToString(players[playerNumber-1].posX, 5));
				timeSincePlayerUpdate = 0;
			}			
		}
	}
	
	
	if(weConnected){
	}else{		
		if(  ofGetElapsedTimeMillis() - connectTime > 5000 ){
			weConnected = tcpClient.setup(server, tcpPort);
			connectTime = ofGetElapsedTimeMillis();
			if(weConnected){
				waitingForPingResponse = false;
				tcpClient.sendAdr(ADR_HANDSHAKE,"player");
				timeSincePing = 1000;
			}
		}
	}
	
	dT = ofGetElapsedTimeMillis();
}

//--------------------------------------------------------------
void testApp::draw(){

	ofSetColor(20, 20, 20);
	mono.drawString("openFrameworks TCP Send Example", 15, 30);

		if(serverConnected){
			monosm.drawString("status: sending pings to server at ole", 15, 55);
			monosm.drawString("latency: "+ofToString(latency)+"ms\n"+
							"player number: "+ofToString(playerNumber)+"\n"+
							 "player1: "+ofToString(players[0].posX)+"\n"+
							  "player2: "+ofToString(players[1].posX), 15, 75);

		}
		else {
			monosm.drawString("status: server not found. launch server app and check ports!\n\nreconnecting in "+ofToString( (5000 -  (ofGetElapsedTimeMillis() - connectTime)) / 1000 )+" seconds", 15, 55);
		}
//	}
	
	monosm.drawString("from server: \n"+msgRx, 15, 270);
	
}


//--------------------------------------------------------------
void testApp::keyPressed(int key){ 

	//you can only type if you're connected 
	/*if(weConnected){
		if(key == 13)key = '\n';
		if(key == 8 || key == 127){
			if( pos != 0 ){pos--;
				msgTx = msgTx.substr(0,pos);
			}else msgTx = "";
		}else{
			msgTx.append(1, (char) key);
			pos++;
		}
		typed = true;
	}*/
}

//--------------------------------------------------------------
void testApp::keyReleased(int key){ 

	
}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){
	players[playerNumber-1].posX = x/(float)ofGetWidth();
}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
	
}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){
	
}

//--------------------------------------------------------------
void testApp::mouseReleased(){

}
